// PaintView.cpp : implementation file
//

#include "stdafx.h"
#include "lc32.h"

#include "lc32Doc.h"
#include "PaintView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define PI			3.14159265358979
#define RADIANS(_x)	((double)((PI*(_x))/180.0))

/////////////////////////////////////////////////////////////////////////////
// CPaintView

IMPLEMENT_DYNCREATE(CPaintView, CView)

CPaintView::CPaintView()
{
}

CPaintView::~CPaintView()
{
}


BEGIN_MESSAGE_MAP(CPaintView, CView)
	//{{AFX_MSG_MAP(CPaintView)
	ON_WM_TIMER()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPaintView drawing

void CPaintView::OnDraw(CDC* pDC)
{
	HANDLE hEvents[2] = {
		m_hWriteEvent,
		m_hReadEvent
	};

	if (WaitForMultipleObjects(2, hEvents, TRUE, 5) != WAIT_OBJECT_0)
		return;

	CLc32Doc* pDoc = GetDocument();
	CRect rc;

	GetClientRect(rc);

	CBitmap bm;
	bm.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

	CDC bmpDC;
	bmpDC.CreateCompatibleDC(pDC);
	CBitmap *pOldBmp = bmpDC.SelectObject(&bm);

	bmpDC.FillSolidRect(rc, RGB(255,255,255));

	int ni = pDoc->GetWidth();
	int nj = pDoc->GetHeight();

	if (ni > 0 && nj > 0)
	{
		CPen mypen1(PS_SOLID, 2, RGB(0,0,255));
		CPen *pOldPen1 = bmpDC.SelectObject(&mypen1);
		CPen *pOldPen2;

		CPen mypen2(PS_SOLID, 2, RGB(255,0,0));
		CPen mypen3(PS_SOLID, 2, RGB(0,0,0));

		int sx = (int)(rc.Width() - 20.0f)/(ni - 1);
		int sy = (int)(rc.Height() - 20.0f)/(nj - 1);
		int xoffset = (int)(0.5f*(rc.Width() - (ni - 1)*sx));
		int yoffset = (int)(0.5f*(rc.Height() - (nj - 1)*sy));
		int j, i, x, y;

		j = 0;
		y = yoffset + j*sy;

		for (i = 0; i < ni; i++)
		{
			int x = xoffset + i*sx;
			int dx = (int)(16.0*cos(RADIANS(pDoc->GetAngle(j,i))));
			int dy = (int)(16.0*sin(RADIANS(pDoc->GetAngle(j,i))));

			if (pDoc->GetTopSurfaceAnchoring(i))
			{
				pOldPen2 = bmpDC.SelectObject(&mypen3);
				bmpDC.MoveTo(x,y);
				bmpDC.LineTo(x,0);
				bmpDC.SelectObject(pOldPen2);
			}

			bmpDC.MoveTo(x-dx,y+dy);
			bmpDC.LineTo(x,y);

			pOldPen2 = bmpDC.SelectObject(&mypen2);
			bmpDC.LineTo(x+dx,y-dy);
			bmpDC.SelectObject(pOldPen2);
		}

		for (j = 1; j < nj - 1; j++)
		{
			int y = yoffset + j*sy;

			for (i = 0; i < ni; i++)
			{
				x = xoffset + i*sx;
				int dx = (int)(16.0*cos(RADIANS(pDoc->GetAngle(j,i))));
				int dy = (int)(16.0*sin(RADIANS(pDoc->GetAngle(j,i))));

				bmpDC.MoveTo(x-dx,y+dy);
				bmpDC.LineTo(x,y);

				CPen *pOldPen2 = bmpDC.SelectObject(&mypen2);
				bmpDC.LineTo(x+dx,y-dy);
				bmpDC.SelectObject(pOldPen2);
			}
		}

		j = nj - 1;
		y = yoffset + j*sy;

		for (i = 0; i < ni; i++)
		{
			x = xoffset + i*sx;
			int dx = (int)(16.0*cos(RADIANS(pDoc->GetAngle(j,i))));
			int dy = (int)(16.0*sin(RADIANS(pDoc->GetAngle(j,i))));

			if (pDoc->GetBottomSurfaceAnchoring(i))
			{
				pOldPen2 = bmpDC.SelectObject(&mypen3);
				bmpDC.MoveTo(x,y);
				bmpDC.LineTo(x,rc.bottom);
				bmpDC.SelectObject(pOldPen2);
			}

			bmpDC.MoveTo(x-dx,y+dy);
			bmpDC.LineTo(x,y);

			CPen *pOldPen2 = bmpDC.SelectObject(&mypen2);
			bmpDC.LineTo(x+dx,y-dy);
			bmpDC.SelectObject(pOldPen2);
		}

		bmpDC.SelectObject(pOldPen1);
	}

	if (!SetEvent(m_hReadEvent))
	{
		TRACE0("CPaintView::OnDraw: unable to set read event to signaled state\n");
	}

	pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &bmpDC, 0, 0, SRCCOPY);
	
	bmpDC.SelectObject(pOldBmp);
	bmpDC.DeleteDC();
}

/////////////////////////////////////////////////////////////////////////////
// CPaintView diagnostics

#ifdef _DEBUG
void CPaintView::AssertValid() const
{
	CView::AssertValid();
}

void CPaintView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CLc32Doc* CPaintView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLc32Doc)));
	return (CLc32Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPaintView message handlers

void CPaintView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	CLc32Doc *pDoc = GetDocument();

	m_hReadEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
	m_hWriteEvent = pDoc->AddClient(m_hReadEvent);

	SetTimer(1, 100, NULL);
}

void CPaintView::OnTimer(UINT nIDEvent) 
{
	Invalidate();
	CView::OnTimer(nIDEvent);
}

BOOL CPaintView::OnEraseBkgnd(CDC* pDC) 
{	
	return TRUE;
}
